class Trie {
public:
    struct node
    {
        string st;
        node* left;
        node* right;
        node(string& word) :st(word), left(nullptr), right(nullptr)
        {}
    };
    node* root;
    Trie() :root(nullptr)
    {
    }

    void insert(string word)
    {
        if (root == nullptr)
        {
            root = new node(word);
        }
        else
        {
            node* father = root, * cur = root;
            bool is_right = strcmp(root->st.c_str(), word.c_str()) > 0 ? true : false;
            while (cur != nullptr)
            {
                father = cur;
                if (strcmp(cur->st.c_str(), word.c_str()) > 0) cur = cur->right, is_right = true;
                else cur = cur->left, is_right = false;
            }

            if (is_right == true) father->right = new node(word);
            else father->left = new node(word);
        }
    }

    bool search(string word)
    {
        if (root == nullptr) return false;
        node* cur = root;
        while (cur != nullptr)
        {
            if (strcmp(cur->st.c_str(), word.c_str()) == 0)return true;
            else if (strcmp(cur->st.c_str(), word.c_str()) > 0) cur = cur->right;
            else cur = cur->left;
        }
        return false;
    }

    bool startsWith(string prefix)
    {
        if (root == nullptr) return false;

        node* cur = root;
        while (cur != nullptr)
        {
            if (cur->st.size() >= prefix.size())
            {
                if (strcmp(cur->st.substr(0, prefix.size()).c_str(), prefix.c_str()) == 0) return true;
            }

            if (strcmp(cur->st.c_str(), prefix.c_str()) > 0) cur = cur->right;
            else cur = cur->left;
        }
        return false;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */